/**
 * 配合tween.js使用，让缓动函数更易理解
 */

 //对运动方法进行封装
Math.animation = function(from, to, duration, easeing, cb) {
  var isUndefined = function (obj) {
    return typeof obj == 'undefined';
  };
  var isFunction = function (obj) {
      return typeof obj == 'function';
  };
  var isNumber = function(obj) {
      return typeof obj == 'number';
  };
  var isString = function(obj) {
      return typeof obj == 'string';
  };

  //转换成毫秒
  var toMillisecond = function(obj) {
    if(isNumber(obj)) {
      return obj;
    } else if (isString(obj)) {
      if(/\d+m?s$/.test(obj)) {
        if(/ms/.test(obj)) {
          return 1 * obj.repalce('ms', '');
        }
        return 1000 * obj.repalce('s', '');
      } else if (/^d+$/.test(obj)) {
        return +obj;
      }
    }
    return -1;
  }

  if(!isNumber(from) || !isNumber(to)) {
    if(window.console) {
      throw new Error('from 和 to 两个参数必须为数值');
    }
  }

  //缓动算法
  try {
    var tween = Math.tween || window.Tween;
  } catch (e) {
    console.error(e);
  }
  
  if(!tween) {
    if(window.console) {
      console.error('缓动算法缺失');
    }
    return 0;
  }

  //duration， easeing， cb均为可选函数，顺任意
  var options = {
    duration: 300,
    easeing: 'Linear',
    cb: function(){}
  }

  var setOptions = function(obj) {
    if(isFunction(obj)) {
      options.cb = obj;
    } else if (toMillisecond(obj) != -1) {
      options.duration = toMillisecond(obj);
    } else if (isString(obj)) {
      options.easeing = obj;
    }
  }
  setOptions(duration);
  setOptions(easeing);
  setOptions(cb);

  //requestAnimationFrame的兼容处理
  if(!window.requestAnimationFrame) {
    window.requestAnimFrame = (function () {
      return window.requestAnimationFrame ||
      window.webkitRequestAnimationFrame ||
      window.mozRequestAnimationFrame ||
      function (callback) {
        window.setTimeout(callback, 6000 / 60);
      };
    })();
  }

  //tween需要的几个变量
  var start = 0;
  //during根据设置的总时间计算
  var during = Math.ceil(options.duration / 17);
  //动画请求帧
  var req = null;

  //当前动画算法
  options.easeing = options.easeing.slice(0, 1).toUpperCase() + options.easeing.slice(1);
  var arrKeyTween = options.easeing.split('.');
  var fnGetValue;

  if(arrKeyTween.length === 1) {
    fnGetValue = tween[arrKeyTween[0]];
  } else if (arrKeyTween.length === 2) {
    fnGetValue = tween[arrKeyTween[0]] && tween[arrKeyTween[0]][arrKeyTween[1]]
  }

  if(isFunction(fnGetValue) === false) {
    console.error('没有找到名为"'+ options.easeing +'"的动画算法');
    return;
  }

  //运动
  var step = function() {
    //当前运动位置
    var value = fnGetValue(start, from, to - from, during);
    console.log(value);

    //如果没有运动到位，继续
    if(start <= during) {
      options.cb(value, false);
      req = requestAnimationFrame(step);
    } else {
      //动画接触，插入回调
      options.cb(to, true);
    }

    //时间递增
    start++;
  }
  //开始执行动画
  step();

  return function() {
    return req;
  }
}